from Tkinter import *
import random

def random_position(max_x, max_y):
	'''The function returns a random position on a screen of dimensions: width
	max_x and height max_y. The result is a tuple of (x,y) coordinates.'''
	assert max_x >= 0, 'Error: max x-coordinate must be greater than 0!'
	assert max_y >= 0, 'Error: max y-coordinate must be greater than 0!'
	x = random.randint(0, max_x)
	y = random.randint(0, max_y)
	return (x, y)

def random_color():
	''' The function returns a random color in hexadecimal notation as a
	string.'''
	result = '#'
	for i in range(6):
		number = random.randint-
		# since hex() returns a string with 0x, we slice the list'
		result += hex(number)[2:]
	return result


def random_color():
	''' The function returns a random color in hexadecimal notation as a
	string.'''
	result = '#'
	for i in range(6):
		number = random.randint(0, 15)
		# since hex() returns a string with 0x, we slice the list'
		result += hex(number)[2:]
	return result

def draw_circle(canvas_name, x, y, radius, color):
	'''This function draws a circle using the 4 arguments provided:
	canvas_name is the object name (canvas) on which the circle is drawn
	color is the circle's fill and outline color
	radius is the radius of the circle
	x, y are the coordinates of the center of the circle.'''
	# (x1, y1) is the position of the lower left corner of the circle
	x1 = x - radius
	y1 = y - radius
	# (x2, y2) is the position of the upper right corner of the circle
	x2 = x1 + 2*radius
	y2 = y1 + 2*radius
	return canvas_name.create_oval(x1, y1, x2, y2, \
								   fill = color, \
								   outline = color)

# Event handlers.

def key_handler(event):
	'''Handle key presses.'''
	global color
	global circles
	key = event.keysym
	if key == 'q':
		quit(0)
	elif key == 'c':
		color = random_color()
	elif key == 'x':
		for circle in circles:
			canvas.delete(circle)
		circles = []
        
def button_handler(event):
	'''Handle left mouse button click events.'''
	size = random_size(5, 25)
	circle = draw_circle(canvas, event.x, event.y, size, color)
	circles.append(circle)

def circle_contains(canvas, circle_handle, x, y):
	'''Returns True if the circle 'circle_handle' contains the point (x, y).'''
	circle_dimensions = canvas.coords(circle_handle)
	# Calculate the circle's radius
	radius = (circle_dimensions[0] - circle_dimensions[2]) / 2
	# Calculate the position of the center of the circle
	center = ((circle_dimensions[0] + circle_dimensions[2]) / 2,
			  (circle_dimensions[1] + circle_dimensions[3]) / 2)
	# Calculate the square of the distance between the give point (x, y)
	# and the circle's center
	distance_squared = (center[0] - x) ** 2 + (center[1] - y) ** 2
	# Return True if radius squared is greater than distance squared, i.e.
	# if the point is within the circle's radius.
	return radius ** 2 >= distance_squared
    
# Graphics commands.

def draw_circle(canvas, color, location, size):
	'''Draws a circle on the canvas 'canvas' with color 'color',
	at (x, y) location 'location', and with radius 'size'.
	Returns the handle of the circle on the canvas.'''
	# (x1, y1) is the position of the lower left corner of the circle
	x1 = location[0] - size
	y1 = location[1] - size
	# (x2, y2) is the position of the upper right corner of the circle
	x2 = x1 + 2*size
	y2 = y1 + 2*size
	return canvas.create_oval(x1, y1, x2, y2, \
								   fill = color, \
								   outline = color)

# Event handlers.

def left_button_handler(event):
	'''Handle left mouse button click events.'''
	global circles, color
	size = random_size(5, 25)
	circle = draw_circle(canvas, color, (event.x, event.y), size)
	circles.append(circle)
        
def right_button_down_handler(event):
	'''Handle right mouse button down events.'''
	global moving_circle, moving_circle_x, moving_circle_y
	stacking_order = canvas.find_all()
	# Find the highest order circle that contains the point on which we're
	# clicking.
	for i in range(len(stacking_order)-1, -1, -1):
		if circle_contains(canvas, stacking_order[i], event.x, event.y):
			moving_circle = stacking_order[i]
			break
    # Execute if we did find a circle to move.
	if moving_circle != -1:
		canvas.lift(moving_circle)
		moving_circle_x = event.x
		moving_circle_y = event.y

def right_button_motion_handler(event):
	'''Handle right mouse button motion events.'''
	global moving_circle_x, moving_circle_y
	# Check if we are actually "holding" a circle
	if moving_circle != -1:
		# Calculate the translation vector
		vector_x = event.x - moving_circle_x
		vector_y = event.y - moving_circle_y
		moving_circle_x = event.x
		moving_circle_y = event.y
		canvas.move(moving_circle, vector_x, vector_y)

def right_button_up_handler(event):
	'''Handle right mouse button up events.'''
	global moving_circle, moving_circle_x, moving_circle_y    
	moving_circle = -1
	moving_circle_x = -1
	moving_circle_y = -1

if __name__ == '__main__':
	root = Tk()
	root.geometry('800x800')
	canvas = Canvas(root, width=800, height=800)
	canvas.pack()
	moving_circle   = -1
	moving_circle_x = -1
	moving_circle_y = -1
	color = random_color()
	circles = []
	# Bind events to handlers.
	root.bind('<Key>', key_handler)
	canvas.bind('<Button-3>',        right_button_down_handler)
	canvas.bind('<B3-Motion>',       right_button_motion_handler)
	canvas.bind('<ButtonRelease-3>', right_button_up_handler)
	canvas.bind('<Button-1>',        left_button_handler)
	# Start it up.
	root.mainloop()